package lumis.service.rss;

import java.util.Collection;

import lumis.portal.PortalException;
import lumis.portal.authentication.SessionConfig;
import lumis.portal.event.AbstractPortalEventObserver;
import lumis.portal.event.IPortalEvent;
import lumis.portal.event.PortalEventFilters;
import lumis.portal.event.IPortalEventFilter;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.serviceinstance.ServiceInstanceConfig;
import lumis.portal.serviceinstance.ServiceInstanceRenderDataChangedEvent;
import lumis.portal.transaction.AbstractTransactionObserver;
import lumis.portal.transaction.ITransactionObserver;
import lumis.portal.transaction.PortalTransactionFactory;
import lumis.portal.user.UserConfig;
import lumis.util.ITransaction;
import lumis.util.log.ILogger;
import lumis.util.log.LoggerFactory;

/**
 * Observer that update the RSS XML file according to the notifications received.
 * 
 * @since 4.1.0
 * @version $Revision: 8948 $ $Date: 2008-02-29 12:40:36 -0300 (Fri, 29 Feb 2008) $
 */
public class RssObserver extends AbstractPortalEventObserver
{
	private static ILogger logger = LoggerFactory.getLogger(RssObserver.class);

	private static class AsyncGenerateRssXml extends AbstractTransactionObserver implements Runnable, ITransactionObserver
	{
		private final ServiceInstanceRenderDataChangedEvent event;

		public AsyncGenerateRssXml(ServiceInstanceRenderDataChangedEvent event)
		{
			this.event = event;
		}

		public void run()
		{
			try
			{
				SessionConfig sessionConfig = ManagerFactory.getAuthenticationManager().impersonate(UserConfig.USER_SYSTEM_ID);
				try
				{
					ITransaction transaction = PortalTransactionFactory.createTransaction();
					try
					{
						transaction.begin();

						for(ServiceInstanceConfig serviceInstanceConfig: event.getServiceInstancesChanged())
						{
							Collection<String> rssIds = RssManagerFactory.getRssManager().getIdsByServiceInstanceId(sessionConfig, serviceInstanceConfig.getId(), transaction);
							
							for(String rssId : rssIds)
							{
								RssConfig rssConfig = RssManagerFactory.getRssManager().get(sessionConfig, rssId, transaction);
								RssManagerFactory.getRssManager().generateRssXmlFile(sessionConfig, rssConfig, null, transaction);
							}
						}
						
						transaction.commit();
					}
					finally
					{
						transaction.dispose();
					}
				}
				finally
				{
					ManagerFactory.getAuthenticationManager().endImpersonation(sessionConfig);
				}
			}
			catch(Exception e)
			{
				logger.error("Exception thrown while generate the rss xml file", e);
			}
		}
		
		@Override
		public void afterCommit() throws PortalException
		{
			Thread thread = new Thread(this, "RssObserver-AsyncGenerateRssXml");
			thread.start();
		}
	}
	
	@Override
	public IPortalEventFilter getEventFilter()
	{
		return PortalEventFilters.byInstanceOf(ServiceInstanceRenderDataChangedEvent.class);
	}

	public void onEvent(IPortalEvent ev) throws PortalException
	{
		ServiceInstanceRenderDataChangedEvent event = (ServiceInstanceRenderDataChangedEvent)ev;
		ITransaction transaction = event.getTransaction();
		transaction.addObserver(new AsyncGenerateRssXml(event));
	}
}
